/* 
 * File:   main.cpp
 * Author: djs
 *
 * Created on February 3, 2011, 4:05 PM
 */

#include <cstdlib>
#include <bitset>
#include "fdecode.h"
#include <fstream>
#include<iostream>
#include<string>
#include "pipe_elements.h"
#include <stdio.h>
#include <stack>
int flushed;
int kill;
bits  flushedby;
 stack <int> rsremovelist;
fstream inputf,outputf;
int lastaddress;
int breakencounter;
int cycle;
using namespace std;
int PC;
map <int,bits> mMemory;
int debug=1;
/*
 * 
 */
int main(int argc, char** argv)
{
    flushed=0;
    kill=0;
    PC=596;
    cycle=1;
    breakencounter=0;
    bits * test;

//    if(argc < 4 )
//    {
//        cout<<"MIPS simulator \nBy : Aswin Damodar, UFID 19461901\n\n\n Usage : mips <inputfile>  <outputfile> <operation> [-T m:n]\n This version only supports the \"dis\" operation , T m:n is also not supported\n";
//        return 0;
//    }
    inputf.open("fibonacci.bin",ios::in|ios::binary);
    outputf.open("output",ios::out);

    //inputf.seekg()
//    if (!inputf.is_open())
//    {
//        cout<<" Sorry try another inputfilename \n";
//        return 0;
//    }
    if (!outputf.is_open())
    {
        cout<<" Sorry try another outputfilename \n";
        return 0;
    }
    //cout<<argv[2];
//    if(string("dis").compare(string(argv[3]))!=0)
//    {
//        cout<<"\nThis version only supports the dis operation\n\n" ; return 0;
//    }
    int startaddress=596;
    test=new bits;
        while(test->read(startaddress))
        {

            
        test->disassemble();
        mInsert(startaddress,*test);
        //test->print();
        startaddress+=4;
        test=new bits;
        }
    lastaddress=startaddress;
    for(int i=596;i<startaddress;i+=4)
    {
        mMemory[i].print();

       //cout<<i<<" ";
    }
    pipeline PIPE;

    while(1)
    {
        int ch;
        cout<<"\n\ncycle <"<<cycle<<">\n\n";
        while(!rsremovelist.empty())
        {
            int rsnum=rsremovelist.top();
            rsremovelist.pop();
            //cout<<"****************Removing********<><><><>"<<PIPE.rRS.station[rsnum].op<<endl;
            PIPE.rRS.setnotbusy(rsnum);
        }
        if(flushed)
        {
            PIPE.rIQ.flush();
            PIPE.rROB.flush(flushedby.issuecycle);
            PIPE.rCDB.flush();
            PIPE.rRS.flush(flushedby.issuecycle);
            PC=PIPE.rBTB.getaddr(flushedby.address);
            cout<<"NEW PC is "<<PC<<"\n";
            flushed=0;
            //cycle++;
        }

        PIPE.fetch();
        PIPE.issue();
        PIPE.execute();
       // if(!flushed)
        PIPE.writeresult();
        //if(!flushed)
        PIPE.commit();

        PIPE.rIQ.fprint();
        PIPE.rBTB.fprint();
        PIPE.rRS.fprint();
        PIPE.rROB.fprint();
        PIPE.rCDB.fprint();
        
        cin>>ch;
        if(ch==0)
            break;
        cycle++;
    }

    inputf.close();
    outputf.close();
        return 0;
}

